import { Module, NestModule, Global } from "@nestjs/common";
import { ConfigService } from "./config.service";
import axios from "axios";

@Global()
@Module({
    providers: [ConfigService],
    exports: [ConfigService],
})
export class ConfigModule implements NestModule {
    constructor(private readonly configService: ConfigService) {}

    public async configure() {
        try {
            let host, port;
            if (process.env.NODE_ENV === "development") {
                host = process.env.DEBUG_HOSTNAME || "127.0.0.1";
                port = parseInt(process.env.DEBUG_PORT) || "443";
            } else {
                ({
                    data: { host = "127.0.0.1", port = "443" },
                } = await axios.get(
                    `http://deploy-service.anyshare.svc.cluster.local:9703/api/deploy-manager/v1/access-addr/app`
                ));
            }

            const {
                protocol: authenticationProtocol,
                hostname: authenticationHostname,
                port: authenticationPort,
            } = new URL(process.env.PUBLIC_AUTHENTICATION_URL || "http://127.0.0.1");
            this.configService.authenticationPublicApi.defaults.hostname = authenticationHostname;
            this.configService.authenticationPublicApi.defaults.https = authenticationProtocol === "https:";
            this.configService.authenticationPublicApi.defaults.port = parseInt(authenticationPort) || undefined;

            const {
                protocol: deployServiceProtocol,
                hostname: deployServiceHostname,
                port: deployServicePort,
            } = new URL(process.env.DEPLOY_SERVICE_URL || "http://127.0.0.1");
            this.configService.deployServiceApi.defaults.hostname = deployServiceHostname;
            this.configService.deployServiceApi.defaults.https = deployServiceProtocol === "https:";
            this.configService.deployServiceApi.defaults.port = parseInt(deployServicePort) || undefined;

            const { protocol: eacpProtocol, hostname: eacpHostname, port: eacpPort } = new URL(
                process.env.PUBLIC_API_BASE || "http://127.0.0.1"
            );
            this.configService.eacpPublicApi.defaults.hostname = eacpHostname;
            this.configService.eacpPublicApi.defaults.https = eacpProtocol === "https:";
            this.configService.eacpPublicApi.defaults.port = parseInt(eacpPort) || undefined;

            this.configService.hydraPublicApi.defaults.baseURL = process.env.HYDRA_PUBLIC_URI || "http://127.0.0.1";

            const { protocol: sharedLinkProtocol, hostname: sharedLinkHostname, port: sharedLinkPort } = new URL(
                process.env.PUBLIC_SHARED_LINK_URL || "http://127.0.0.1"
            );
            this.configService.sharedLinkPublicApi.defaults.hostname = sharedLinkHostname;
            this.configService.sharedLinkPublicApi.defaults.https = sharedLinkProtocol === "https:";
            this.configService.sharedLinkPublicApi.defaults.port = parseInt(sharedLinkPort) || undefined;

            this.configService.hydraInfo = {
                clientId: process.env.CLIENT_ID || "",
                clientSecret: process.env.CLIENT_SECRET || "",
                redirectUri: `https://${host}:${port}/anyshare/oauth2/login/callback`,
                postLogoutRedirectUri: `https://${host}:${port}/anyshare/oauth2/logout/callback`,
            };

            this.configService.publicInfo = {
                baseUri: `https://${host}:${port}`,
                hostname: host,
                https: true,
            };
        } catch (err) {
            console.error("Failed to connect to deploy-service.");
            throw new Error("Failed to connect to deploy-service.");
        }
    }
}
